package org.example.MedicalCrowdsourcing.controller;

import org.example.MedicalCrowdsourcing.dto.ProjectDto;
import org.example.MedicalCrowdsourcing.dto.ProjectDataDto;
import org.example.MedicalCrowdsourcing.dto.CreateProjectRequest;
import org.example.MedicalCrowdsourcing.dto.SubmitDataRequest;
import org.example.MedicalCrowdsourcing.model.dto.ProjectCreateDTO;
import org.example.MedicalCrowdsourcing.model.dto.ProjectDTO;
import org.example.MedicalCrowdsourcing.model.dto.ProjectDataDTO;
import org.example.MedicalCrowdsourcing.model.entity.User;
import org.example.MedicalCrowdsourcing.service.ProjectService;
import org.example.MedicalCrowdsourcing.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/projects")
public class ProjectController {

    @Autowired
    private ProjectService projectService;

    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<ProjectDto> createProject(@Valid @RequestBody CreateProjectRequest request, 
                                                 Authentication authentication) {
        // 获取当前登录用户
        String username = authentication.getName();
        
        // 从用户名获取用户ID
        Long researcherId = userService.findByUsername(username)
                .map(User::getId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 创建ProjectCreateDTO对象
        ProjectCreateDTO projectCreateDTO = new ProjectCreateDTO();
        projectCreateDTO.setTitle(request.getTitle());
        projectCreateDTO.setDescription(request.getDescription());
        projectCreateDTO.setRequiredParticipants(request.getRequiredParticipants());
        
        // 将List<String>转换为单个String，用逗号分隔
        projectCreateDTO.setRequiredDataTypes(String.join(",", request.getDataTypes()));
        
        // 设置其他必要的字段
        projectCreateDTO.setStartDate(LocalDateTime.now());
        projectCreateDTO.setEndDate(LocalDateTime.now().plusMonths(1)); // 默认一个月后结束
        
        // 处理报酬信息
        if (request.getRewards() != null && !request.getRewards().isEmpty()) {
            // 简单处理：取Map中的第一个值作为报酬
            BigDecimal compensationAmount = BigDecimal.valueOf(
                    request.getRewards().values().stream().findFirst().orElse(0)
            );
            projectCreateDTO.setCompensationAmount(compensationAmount);
        } else {
            projectCreateDTO.setCompensationAmount(BigDecimal.ZERO);
        }
        
        // 调用service方法创建项目
        ProjectDTO createdProject = projectService.createProject(projectCreateDTO, researcherId);
        
        // 转换为响应DTO
        ProjectDto responseDto = convertToProjectDto(createdProject);
        
        return new ResponseEntity<>(responseDto, HttpStatus.CREATED);
    }

    @GetMapping
    public ResponseEntity<List<ProjectDto>> getAllProjects() {
        // 调用service方法获取所有项目
        List<ProjectDTO> projectDTOList = projectService.getAllProjects();
        
        // 将ProjectDTO列表转换为ProjectDto列表
        List<ProjectDto> projectDtoList = projectDTOList.stream()
                .map(this::convertToProjectDto)
                .collect(Collectors.toList());
                
        return ResponseEntity.ok(projectDtoList);
    }

    @GetMapping("/{id}")
    public ResponseEntity<ProjectDto> getProjectById(@PathVariable Long id) {
        // 调用service方法获取项目
        ProjectDTO projectDTO = projectService.getProjectById(id);
        
        // 转换为响应DTO
        ProjectDto projectDto = convertToProjectDto(projectDTO);
        
        return ResponseEntity.ok(projectDto);
    }

    @PostMapping("/{id}/participate")
    public ResponseEntity<ProjectDto> participateInProject(@PathVariable Long id, 
                                                       Authentication authentication) {
        // 获取当前登录用户
        String username = authentication.getName();
        
        // 从用户名获取用户ID
        Long participantId = userService.findByUsername(username)
                .map(User::getId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 调用service方法加入项目
        ProjectDTO projectDTO = projectService.joinProject(id, participantId);
        
        // 转换为响应DTO
        ProjectDto projectDto = convertToProjectDto(projectDTO);
        
        return ResponseEntity.ok(projectDto);
    }

    @PostMapping("/{id}/submit")
    public ResponseEntity<ProjectDataDto> submitData(@PathVariable Long id, 
                                                @Valid @RequestBody SubmitDataRequest request,
                                                Authentication authentication) {
        // 获取当前登录用户
        String username = authentication.getName();
        
        // 从用户名获取用户ID
        Long participantId = userService.findByUsername(username)
                .map(User::getId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 创建ProjectDataDTO对象
        ProjectDataDTO dataDTO = new ProjectDataDTO();
        dataDTO.setProjectId(id);
        dataDTO.setParticipantId(participantId);
        dataDTO.setDataContent(request.getData().toString()); // 简单转为字符串
        dataDTO.setDataType("JSON"); // 假设数据类型为JSON
        
        // 调用service方法提交数据
        ProjectDataDTO resultDTO = projectService.submitData(id, participantId, dataDTO);
        
        // 转换为响应DTO
        ProjectDataDto responseDto = convertToProjectDataDto(resultDTO);
        
        return new ResponseEntity<>(responseDto, HttpStatus.CREATED);
    }

    @PostMapping("/{id}/close")
    public ResponseEntity<ProjectDto> closeProject(@PathVariable Long id, 
                                               Authentication authentication) {
        // 调用service方法关闭项目
        ProjectDTO projectDTO = projectService.closeProject(id);
        
        // 转换为响应DTO
        ProjectDto projectDto = convertToProjectDto(projectDTO);
        
        return ResponseEntity.ok(projectDto);
    }

    /**
     * 更新项目
     */
    @PutMapping("/{id}")
    public ResponseEntity<ProjectDto> updateProject(@PathVariable Long id, 
                                               @Valid @RequestBody ProjectCreateDTO updateRequest,
                                               Authentication authentication) {
        // 获取当前登录用户
        String username = authentication.getName();
        User currentUser = userService.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        try {
            // 调用服务方法更新项目，传入当前用户进行权限验证
            ProjectDTO updatedProject = projectService.updateProject(id, updateRequest, currentUser);
            return ResponseEntity.ok(convertToProjectDto(updatedProject));
        } catch (AccessDeniedException e) {
            // 权限不足，返回403
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        } catch (Exception e) {
            // 其他错误，返回400
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
        }
    }

    /**
     * 删除项目
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteProject(@PathVariable Long id, Authentication authentication) {
        // 获取当前登录用户
        String username = authentication.getName();
        User currentUser = userService.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        try {
            // 调用服务方法删除项目，传入当前用户进行权限验证
            projectService.deleteProject(id, currentUser);
            return ResponseEntity.noContent().build();
        } catch (AccessDeniedException e) {
            // 权限不足，返回403
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        } catch (Exception e) {
            // 其他错误，返回400
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
    }

    /**
     * 将ProjectDTO转换为ProjectDto
     */
    private ProjectDto convertToProjectDto(ProjectDTO projectDTO) {
        ProjectDto dto = new ProjectDto();
        dto.setId(projectDTO.getId());
        dto.setTitle(projectDTO.getTitle());
        dto.setDescription(projectDTO.getDescription());
        dto.setRequiredParticipants(projectDTO.getRequiredParticipants());
        dto.setCurrentParticipants(projectDTO.getParticipantsCount() != null ? projectDTO.getParticipantsCount() : 0);
        
        // 将逗号分隔的数据类型转换回列表
        if (projectDTO.getRequiredDataTypes() != null) {
            dto.setDataTypes(Arrays.asList(projectDTO.getRequiredDataTypes().split(",")));
        }
        
        // 将报酬信息转换为Map
        Map<String, Integer> rewards = new HashMap<>();
        if (projectDTO.getCompensationAmount() != null) {
            rewards.put("基本报酬", projectDTO.getCompensationAmount().intValue());
        }
        dto.setRewards(rewards);
        
        dto.setStatus(projectDTO.getStatus());
        dto.setResearcherUsername(projectDTO.getResearcherName());
        dto.setCreatedAt(projectDTO.getCreatedAt());
        dto.setLastUpdatedAt(projectDTO.getUpdatedAt());
        return dto;
    }
    
    /**
     * 将ProjectDataDTO转换为ProjectDataDto
     */
    private ProjectDataDto convertToProjectDataDto(ProjectDataDTO dataDTO) {
        ProjectDataDto dto = new ProjectDataDto();
        dto.setId(dataDTO.getId());
        dto.setProjectId(dataDTO.getProjectId());
        
        // 尝试解析JSON数据
        Map<String, Object> dataMap = new HashMap<>();
        try {
            // 简单处理，实际应用可能需要更复杂的JSON解析
            dataMap.put("content", dataDTO.getDataContent());
            dataMap.put("type", dataDTO.getDataType());
        } catch (Exception e) {
            dataMap.put("error", "无法解析数据");
        }
        
        dto.setData(dataMap);
        dto.setStatus(dataDTO.getStatus());
        dto.setSubmittedAt(dataDTO.getSubmissionDate());
        
        // 尝试从UserService获取用户名
        userService.findById(dataDTO.getParticipantId())
            .ifPresent(user -> dto.setParticipantUsername(user.getUsername()));
        
        return dto;
    }
} 